package cn.yuxiaoyuan.service.impl;

import cn.dev33.satoken.stp.SaLoginConfig;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.yuxiaoyuan.constants.RedisCacheConstants;
import cn.yuxiaoyuan.exception.GlobalException;
import cn.yuxiaoyuan.pojo.domain.Login;
import cn.yuxiaoyuan.mapper.LoginMapper;
import cn.yuxiaoyuan.pojo.ro.LoginRo;
import cn.yuxiaoyuan.result.JSONResult;
import cn.yuxiaoyuan.service.ILoginService;
import cn.yuxiaoyuan.template.AssertUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 登录表 服务实现类
 * </p>
 *
 * @author whale
 * @since 2025-06-13
 */
@Service
public class LoginServiceImpl extends ServiceImpl<LoginMapper, Login> implements ILoginService {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private LoginMapper loginMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Override
    public JSONResult login(LoginRo loginRo) {
        LambdaQueryWrapper<Login> wrapper = new LambdaQueryWrapper<Login>()
                .eq(Login::getUsername, loginRo.getUsername())
                .eq(Login::getType, loginRo.getType());
        //登录的流程是啥？
        Login login = super.getOne(wrapper);
        if(login == null){
            throw new GlobalException("用户名或密码错误");
        }
        //密码验证

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("token","xxxxxxxx");
        login.setPassword("");
        map.put("login",login);
        map.put("permissions","");
        //有用户密码验证
        return JSONResult.success(map);
    }

    @Override
    public void initUserRoleAndPermission(Login login) {
        //加载 当前用户的角色  和 权限
        List<String> userRole = loginMapper.getUserRole(login.getId());
        List<String> userPermission = loginMapper.getUserPermission(login.getId());
        //保存到redis里面
        redisTemplate.opsForValue().set(RedisCacheConstants.USER_ROLE_KEY+login.getId(),userRole);
        redisTemplate.opsForValue().set(RedisCacheConstants.USER_PERMISSION_KEY+login.getId(),userPermission);
        saTokenLogin(login);
    }

    //执行SaToken登录逻辑
    public SaTokenInfo saTokenLogin(Login login){
        StpUtil.login(login.getId(), SaLoginConfig
                //根据需要封装扩展参数
                .setExtra("username", login.getUsername())
                .setExtra("type", login.getType())
                .setExtra("avatar", login.getAvatar())
                .setExtra("phone", login.getPhone())
                .setExtra("admin", login.getAdmin())
                .setExtra("nickName", login.getNickName())
                //加载权限
//                .setExtra("permissions", )
//                .setExtra("roles",)
                .setExtra("openId", login.getOpenId()));
        return StpUtil.getTokenInfo();
    }

    @Override
    public JSONResult adminLogin(Login login) {

        //查询用户
        Login loginFromDB = super.getOne(new LambdaQueryWrapper<Login>().eq(Login::getUsername, login.getUsername()));
        AssertUtil.isNotNull(loginFromDB,"用户名不存在");

        //比较密码
        boolean passIsOk = passwordEncoder.matches(login.getPassword(),loginFromDB.getPassword());
        AssertUtil.isTrue(passIsOk,"密码错误");

        //执行SaToken登录
        SaTokenInfo saTokenInfo = saTokenLogin(loginFromDB);

        Map<String,Object> result = new HashMap<>();
        result.put("token",saTokenInfo);
        //前端要使用到权限和login信息
        result.put("permissions",StpUtil.getExtra("permissions"));
        loginFromDB.setPassword(null);
        result.put("login",loginFromDB);

        return JSONResult.success(result);
    }
}
